// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"

#include "XamlApplication.h"
#include "XamlHost.h"

#if defined(RNW_NEW_ARCH)

#include "..\codegen\react\components\rnwcore\XamlHost.g.h"

namespace winrt::Microsoft::ReactNative {

struct XamlHostComponentView : public winrt::implements<XamlHostComponentView, winrt::IInspectable>,
                               ::Microsoft::ReactNativeSpecs::BaseXamlHost<XamlHostComponentView> {
  void InitializeContentIsland(
      const winrt::Microsoft::ReactNative::Composition::ContentIslandComponentView &islandView) noexcept {
    winrt::Microsoft::ReactNative::Xaml::implementation::XamlApplication::EnsureCreated();

    m_xamlIsland = winrt::Microsoft::UI::Xaml::XamlIsland{};

    islandView.Connect(m_xamlIsland.ContentIsland());
  }

  void MountChildComponentView(
      const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
      const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &args) noexcept override {
    // Add the xaml child to the m_xamlIsland here.
    auto childXamlControl = args.Child().UserData().as<winrt::Microsoft::ReactNative::Xaml::IXamlControl>();
    if (childXamlControl) {
      auto xamlElement = childXamlControl.GetXamlElement();
      m_xamlIsland.Content(xamlElement);
    }
  }

  void UnmountChildComponentView(
      const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
      const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &) noexcept override {
    m_xamlIsland.Content(nullptr);
  }

 private:
  winrt::Microsoft::UI::Xaml::XamlIsland m_xamlIsland{nullptr};
};

} // namespace winrt::Microsoft::ReactNative

void RegisterXamlHostComponentView(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) {
  ::Microsoft::ReactNativeSpecs::RegisterXamlHostNativeComponent<winrt::Microsoft::ReactNative::XamlHostComponentView>(
      packageBuilder,
      [](const winrt::Microsoft::ReactNative::Composition::IReactCompositionViewComponentBuilder &builder) {
        builder.SetContentIslandComponentViewInitializer(
            [](const winrt::Microsoft::ReactNative::Composition::ContentIslandComponentView &islandView) noexcept {
              auto userData = winrt::make_self<winrt::Microsoft::ReactNative::XamlHostComponentView>();
              userData->InitializeContentIsland(islandView);
              islandView.UserData(*userData);
            });
      });
}

#endif // defined(RNW_NEW_ARCH) && defined(USE_EXPERIMENTAL_WINUI3)
